import 'dart:convert';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:yun/mqtt/result_handler.dart';
import 'package:yun/util/toast_util.dart';

import '../main.dart';
import '../serial/send_helper.dart';
import 'mqtt.dart';

class MqttHelper{

  ResultHandler resultHandler = ResultHandler();

  static final Map<String, MqttHelper> _cache = <String, MqttHelper>{};
  final String url;
  final String clientId;
  final int port;


  factory MqttHelper(String url,String clientId,int port) {
    return _cache.putIfAbsent(url, () => MqttHelper._internal(url,clientId,port));
  }

  MqttHelper._internal(this.url,this.clientId,this.port){
    initMqtt(url,clientId,port);
  }

  late MqttServerClient _client;

  void initMqtt(url,clientId,port){

    _client = MqttServerClient.withPort(url, clientId, port);
    _client.logging(on: true);
    _client.port = port;
    _client.setProtocolV311();
    _client.keepAlivePeriod = 60;
    _client.onConnected = onConnected;
    _client.onDisconnected = onDisconnected;
    _client.onUnsubscribed = onUnsubscribed;
    _client.onSubscribed = onSubscribed;
    _client.onSubscribeFail = onSubscribeFail;
    _client.pongCallback = pong;

    final connMessage = MqttConnectMessage()
        .withWillTopic("yss/$clientId")
        .withWillMessage('{"cmd": "100000", "deviceVersion":"xy_$currentVersion", "deviceID": "$clientId"}')
        .startClean()
        .withWillQos(MqttQos.atLeastOnce);
    _client.connectionMessage = connMessage;
    _connect();
  }


  _connect() async {

    try{
      await _client.connect("xycs","yss&xy");
    }catch (e) {
      print("连接异常: $e");
      _client.disconnect();
      return;
    }

    if (_client.connectionStatus!.state == MqttConnectionState.connected) {
      print("已经连接....");
    } else {
      print("连接失败啦 状态===${_client.connectionStatus}");
      _client.disconnect();
      return;
    }

    var scribeTopic = "bookcase/$clientId";

    _client.subscribe(scribeTopic, MqttQos.atLeastOnce);
    _client.updates?.listen((event) {
      var receivedMessage = event[0].payload as MqttPublishMessage;
      // var bytes = recvMessage.payload.message;
      var message = const Utf8Decoder().convert(receivedMessage.payload.message);
      // print("原始数据-----：${recvMessage.payload.message}");
      resultHandler.handler(event[0].topic,jsonDecode(message));
      print("接收到了主题${event[0].topic}的消息： ${message}");
    });

  }

  void onConnected() {
    print("连接成功....");
    try{
      hfSerialPortHelper.sendData(checkStatus());
    }catch(e){
      print(e);
    }

  }

  void onDisconnected() {
    print("连接断开");
    toastWarn('连接断开');
    Future.delayed(const Duration(seconds: 10),(){
      _connect();
    });
  }

  void onUnsubscribed(String? topic) {
    print("取消订阅 $topic");
  }

  void onSubscribed(String topic) {
    print("订阅 $topic 成功");
  }

  void onSubscribeFail(String topic) {
    print("订阅主题: $topic 失败");
  }

  void pong() {
    print("Ping的响应");
  }

  void push(String message){
    var builder = MqttClientPayloadBuilder();
    builder.addUTF8String(message);
    _client.publishMessage("yss/$clientId", MqttQos.atLeastOnce, builder.payload!);
    print(const Utf8Decoder().convert( builder.payload!));
  }

  void dispose() {
    print('关闭');
    _client.disconnect();
  }
}